package com.syf.controller;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.syf.domain.User;
import com.syf.domain.UserAuthAuditRecord;
import com.syf.domain.UserAuthInfo;
import com.syf.dto.UserDto;
import com.syf.feign.UserServiceFeign;
import com.syf.model.*;
import com.syf.service.UserAuthAuditRecordService;
import com.syf.service.UserAuthInfoService;
import com.syf.service.UserService;
import com.syf.vo.UseAuthInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/users")
@Api(tags = "会员的控制器")
public class UserController  implements UserServiceFeign {  //基础Feign，admin模块就可以远程调用 其接口实现方法


    @Autowired
    private UserService userService; //用户

    @Autowired
    private UserAuthAuditRecordService userAuthAuditRecordService; //用户审核历史记录


    @Autowired
    private UserAuthInfoService userAuthInfoService; //用户认证信息


    @GetMapping
    @ApiOperation(value = "1.分页-条件查询 -> 会员的列表【后台人员操作】")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "会员的手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的Id,精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实名称"),
            @ApiImplicitParam(name = "status", value = "会员的状态")

    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> findByPage(@ApiIgnore Page<User> page, String mobile, Long userId, String userName, String realName, Integer status) {
        page.addOrder(OrderItem.desc("last_update_time"));
        Page<User> userPage = userService.findByPage(page, mobile, userId, userName, realName, status, null);
        return R.ok(userPage);
    }


    @PostMapping("/status")
    @ApiOperation(value = "2.修改用户的状态【后台人员操作】")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "会员的id"),
            @ApiImplicitParam(name = "status", value = "会员的状态"),
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateStatus(Long id, Byte status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        boolean updateById = userService.updateById(user);
        if (updateById) {
            return R.ok("更新成功");
        }
        return R.fail("更新失败");
    }


    @PatchMapping
    @ApiOperation(value = "3.修改用户信息【后台人员操作】")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "会员的json数据"),
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateStatus(@RequestBody @Validated User user) {
        boolean updateById = userService.updateById(user);
        if (updateById) {
            return R.ok("更新成功");
        }
        return R.fail("更新失败");
    }

    @GetMapping("/info")
    @ApiOperation(value = "4.通过用户的Id 查询会员的详细信息【后台人员操作】")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "会员的Id")
    })
    public R<User> userInfo(Long id) {
        User user = userService.getById(id);
        return R.ok(user);
    }



    @GetMapping("/directInvites")
    @ApiOperation(value = "5.通过用户的Id 查询该用户直接邀请的用户列表【后台人员操作】")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "该用户的Id"),
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),

    })
    public R<Page<User>> getDirectInvites(@ApiIgnore Page<User> page, Long userId) {
        Page<User> userPage = userService.findDirectInvitePage(page, userId);
        return R.ok(userPage);
    }


    @GetMapping("/auths")
    @ApiOperation(value = "6.条件分页查询 -> 用户的审核列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "会员的手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的Id,精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实名称"),
            @ApiImplicitParam(name = "reviewsStatus", value = "会员的状态")   //多一个参数

    })
    public R<Page<User>> findUserAuths(@ApiIgnore Page<User> page, String mobile, Long userId, String userName, String realName, Integer reviewsStatus) {
        Page<User> userPage = userService.findByPage(page, mobile, userId, userName, realName, null, reviewsStatus);
        return R.ok(userPage);
    }



    @GetMapping("/auth/info")
    @ApiOperation(value = "【审核时/通过后可 查看】7.查询指定用户的认证详情(user:用户信息, userAuthInfoList:[obj]认证照片, userAuditRecordList:[obj]审核历史)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的Id")
    })
    public R<UseAuthInfoVo> getUseAuthInfo(Long id) {

        User user = userService.getById(id);  //1.查询指定用户信息
        List<UserAuthInfo> userAuthInfoList = null; //用户认证的详情列表
        List<UserAuthAuditRecord> userAuthAuditRecordList = null; //用户审核历史

        if (user != null) {
            Integer reviewsStatus = user.getReviewsStatus();
            if (reviewsStatus == null || reviewsStatus == 0) { //认证状态: (认证状态：0-未认证；1-初级实名认证；2-高级实名认证)
                // 2.用户没有审核记录
                userAuthAuditRecordList = Collections.emptyList();
                // 3.用户未被认证,我们需要通过 用户的ID [按创建时间查询最近3条]用户的认证列表(userId非该表的id字段)
                userAuthInfoList = userAuthInfoService.getUserAuthInfoByUserId(id); //是null还是 正在申请高级认证

            } else {
                // 2.用户有审核记录【查询最近时间的三次审核记录(每次审核都有一个唯一的 auth_code)】
                userAuthAuditRecordList = userAuthAuditRecordService.getUserAuthAuditRecordList(id);
                // 3.通过 用户每组审核记录唯一标识auth_code  -> 该次审核的所有认证信息(身份证的正、反、手持照片[多个])
                UserAuthAuditRecord userAuthAuditRecord = userAuthAuditRecordList.get(0);// 最近被认证的一个记录
                Long authCode = userAuthAuditRecord.getAuthCode(); // 认证的唯一标识
                userAuthInfoList = userAuthInfoService.getUserAuthInfoByCode(authCode);
            }
        }
        return R.ok(new UseAuthInfoVo(user, userAuthInfoList, userAuthAuditRecordList));
    }




    /**
     * 审核的本质:
     *    在于对一组图片(唯一Code)的认可,符合条件,审核通过
     *
     * 审核:
     *    1 修改user 里面的reviewStatus
     *    2 在authAuditRecord 审核表 里面添加一条记录
     */
    @PostMapping("/auths/status")
    @ApiOperation(value = "8.对用户进行审核 -- 修改用户的审核状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的ID"),
            @ApiImplicitParam(name = "authStatus", value = "用户的审核状态"),
            @ApiImplicitParam(name = "authCode", value = "一组图片的唯一标识【审核时 前端给的】"),
            @ApiImplicitParam(name = "remark", value = "审核拒绝的原因(拒绝的时候才有)"),
    })
    public R updateUserAuthStatus(@RequestParam(required = true) Long id, @RequestParam(required = true) Byte authStatus, @RequestParam(required = true) Long authCode, String remark) {
        userService.updateUserAuthStatus(id, authStatus, authCode, remark);
        return R.ok();
    }


    @GetMapping("/current/info")
    @ApiOperation(value = "点击‘个人中心’ -》 获取当前登录用户对象的信息")
    public R<User> currentUserInfo() {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userService.getById(Long.valueOf(idStr));
        System.out.println("邀请码："+user.getInviteCode());
        user.setPassword("****");
        user.setPaypassword("***");
        user.setAccessKeyId("****");
        user.setAccessKeySecret("******"); //频闭重要信息
        return R.ok(user);
    }


    @PostMapping("/authAccount")
    @ApiOperation(value = "用户进行 身份证实名认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAuthForm", value = "userAuthFormjson数据")
    })
    public R identifyCheck(@RequestBody UserAuthForm userAuthForm) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString(); //从上下文中获取该用户的id
        boolean isOk = userService.identifyVerify(Long.valueOf(idStr), userAuthForm);
        if (isOk) {
            return R.ok();
        }
        return R.fail("认证失败");
    }

    @PostMapping("/authUser")
    @ApiOperation(value = "用户进行高级认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "imgs", value = "用户的图片地址")
    })
    public R authUser(@RequestBody String[] imgs) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        userService.authUser(Long.valueOf(idStr), Arrays.asList(imgs));
        return R.ok();
    }


    @PostMapping("/updatePhone")
    @ApiOperation(value = "修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updatePhoneParam", value = "updatePhoneParam 的json数据")
    })
    public R updatePhone(@RequestBody UpdatePhoneParam updatePhoneParam) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean isOk = userService.updatePhone(Long.valueOf(idStr), updatePhoneParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("修改失败");
    }

    @GetMapping("/checkTel")
    @ApiOperation(value = "点击 新手机号发送验证码时: 检查新的手机号是否可用,如可用,则给该新手机发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "新的手机号"),
            @ApiImplicitParam(name = "countryCode", value = "手机号的区域")
    })
    public R checkNewPhone(@RequestParam(required = true) String mobile, @RequestParam(required = true) String countryCode) {
        boolean isOk = userService.checkNewPhone(mobile, countryCode);
        return isOk ? R.ok() : R.fail("新的手机号校验失败");
    }

    @PostMapping("/updateLoginPassword")
    @ApiOperation(value = "修改用户的登录密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginParam", value = "修改用户的登录密码")
    })
    public R updateLoginPwd(@RequestBody @Validated UpdateLoginParam updateLoginParam) {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.updateUserLoginPwd(userId, updateLoginParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("修改失败");
    }


    @PostMapping("/updatePayPassword")
    @ApiOperation(value = "修改用户的交易密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginParam", value = "修改用户的交易密码")
    })
    public R updatePayPwd(@RequestBody @Validated UpdateLoginParam updateLoginParam) {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.updateUserPayPwd(userId, updateLoginParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("修改失败");
    }


    @PostMapping("/setPayPassword")
    @ApiOperation(value = "重新设置交易密码")
    public R setPayPassword(@RequestBody @Validated UnsetPayPasswordParam unsetPayPasswordParam) {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.unsetPayPassword(userId, unsetPayPasswordParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("重置失败");
    }

    @GetMapping("/invites")
    @ApiOperation(value = "查询被该用户的邀请人的列表")
    public R<List<User>> getUserInvites() {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        List<User> users = userService.getUserInvites(userId);
        return R.ok(users);
    }

    @PostMapping("/register")
    @ApiOperation(value = "用户的注册")
    public R register(@RequestBody @Validated RegisterParam registerParam) {
        boolean isOk = userService.register(registerParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("注册失败");
    }


    @PostMapping("/setPassword")
    @ApiOperation(value = "用户重置密码(忘了密码？)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "unSetPasswordParam", value = "unSetPasswordParam json")
    })
    public R unsetPassword(@RequestBody @Validated UnSetPasswordParam unSetPasswordParam) {
        boolean isOk = userService.unsetLoginPwd(unSetPasswordParam);
        if (isOk) {
            return R.ok();
        }
        return R.fail("重置失败");
    }


    /**
     * 用于admin-service 里面远程调用member-service
     * @param ids 会员id集合
     * @return
     */
    @Override
    public Map<Long, UserDto> getBasicUsers(List<Long> ids, String userName, String mobile) {
        Map<Long, UserDto> userDtos = userService.getBasicUsers(ids,  userName,  mobile);
        return userDtos;
    }



}
